import numpy as np
import os


# 加载数据
def load_data(path):
    files = os.listdir(path)

    # 存储数据
    x = np.empty((len(files), 1024), dtype=int)
    y = np.empty((len(files)), dtype=int)

    for i in range(len(files)):
        with open(path + files[i]) as fr:
            lines = fr.readlines()

        # 读取一个文件，转为1024维向量
        x_i = []
        for line in lines:
            line = line.strip()
            x_i.extend(list(line))

        x[i] = np.array(x_i, dtype=int)
        y[i] = files[i].split('_')[0]

    return x, y


x, y = load_data('../data/手写数字_训练/')
test_x, test_y = load_data('../data/手写数字_测试/')


def knn(_x, k=3):
    temp = _x - x
    temp = np.power(temp, 2)
    temp = temp.sum(axis=1)
    temp = np.sqrt(temp)
    argsort = temp.argsort()  # [3 2 1 0]
    result = y[argsort][:k]  # [1 1 0]
    return np.bincount(result).argmax()  # 取众数


# 进行测试
correct = 0
for i in range(len(test_x)):
    pred = knn(test_x[i], k=10)
    if pred == test_y[i]:
        correct += 1
print(correct / len(test_x))

# 优点：简单，没有训练的过程，计算到样本点的距离，哪个类别的票最大是哪个
# 缺点：运算效率特别低
